/*
* Created by zhouli on 19/1/9
* Email li.zhou@huilianyi.com
* 列表前端转树结构
* 已经有至少三个地方用到这种逻辑
* 后端返回列表，需要前端处理为树结构
* */
//后端给出结构如下
/*
let listExample = [
  {
    "tenantId": null,
    "resourceId": "500",
    "permissionId": "1077167530856054786",
    "operationType": "RW",
    "resourceName": "订票管理",
    "parentId": "0"
  },
  {
    "tenantId": null,
    "resourceId": "300100100",
    "permissionId": "1077167530856054786",
    "operationType": "RW",
    "resourceName": "预算组织定义",
    "parentId": "300100"
  },
  {
    "tenantId": null,
    "resourceId": "300100",
    "permissionId": "1077167530856054786",
    "operationType": "RW",
    "resourceName": "预算组织定义",
    "parentId": "300"
  },
  {
    "tenantId": null,
    "resourceId": "300200",
    "permissionId": "1077167530856054786",
    "operationType": "RW",
    "resourceName": "公司组",
    "parentId": "300"
  },
  {
    "tenantId": null,
    "resourceId": "300300",
    "permissionId": "1077167530856054786",
    "operationType": "RW",
    "resourceName": "成本中心组",
    "parentId": "300"
  },
  {
    "tenantId": null,
    "resourceId": "300",
    "permissionId": "1077167530856054786",
    "operationType": "RW",
    "resourceName": "预算设置",
    "parentId": "0"
  }
]
* */
// 处理之后的结构
/*
let resultExample = [
  {
    "tenantId": null,
    "resourceId": "500",
    "permissionId": "1077167530856054786",
    "operationType": "RW",
    "resourceName": "订票管理",
    "parentId": "0"
  },
  {
    "tenantId": null,
    "resourceId": "300",
    "permissionId": "1077167530856054786",
    "operationType": "RW",
    "resourceName": "预算设置",
    "parentId": "0",
    children: [
      {
        "tenantId": null,
        "resourceId": "300200",
        "permissionId": "1077167530856054786",
        "operationType": "RW",
        "resourceName": "公司组",
        "parentId": "300",
        children: [
          {
            "tenantId": null,
            "resourceId": "300100",
            "permissionId": "1077167530856054786",
            "operationType": "RW",
            "resourceName": "预算组织定义",
            "parentId": "300",
            children: [
              {
                "tenantId": null,
                "resourceId": "300100100",
                "permissionId": "1077167530856054786",
                "operationType": "RW",
                "resourceName": "预算组织定义",
                "parentId": "300100"
              }
            ]
          },
          {
            "tenantId": null,
            "resourceId": "300300",
            "permissionId": "1077167530856054786",
            "operationType": "RW",
            "resourceName": "成本中心组",
            "parentId": "300"
          }
        ]
      }
    ]
  }
]
* */

/*
* 传入配置
* 1.转换
* 2.前端过滤搜索
* */
class ListTranformTree {
  constructor(options, nodeConfig) {
    this.resultTree = [];
    this.originList = [];
    this.options = options;
    this.nodeConfig = nodeConfig;
    this.init();
  }

  //通过key,id ,获取目标节点
  getTargetNodeByKey(list, val) {
    let len = list.length;
    for (let i = 0; i < len; i++) {
      if (list[i].id === val) {
        return list[i];
      }
      if (list[i].children) {
        let res = this.getTargetNodeByKey(list[i].children, val);
        if (res) {
          return res;
        }
      }
    }
  }

  //过滤树：返回树搜索的节点被标记
  //只返回被搜索到的节点与父节点
  getSuperFilterTree(keyword) {

    let list = this.deepCopy(this.originList);
    list.map((item) => {
      if (keyword && keyword.length && keyword.length > 0) {
        if (item[this.options.filterKey].match(keyword)) {
          item._filter = true;
        } else {
          item._filter = false;
        }
      } else {
        item._filter = false;
      }
    });
    let resultTree = this.convertListToTree(list);
    let isLeave = {
      val: false
    };
    resultTree = resultTree.map(item => {
      isLeave.val = false;
      deepTraversal(item, isLeave);
      if (isLeave.val) {
        return item;
      }
    })

    //深度遍历tree,把树形节点转为list
    function deepTraversal(node, isLeave) {
      if (node !== null) {
        if (node._filter) {
          isLeave.val = true;
        }
        let children = node.children;
        if (children) {
          for (let i = 0; i < children.length; i++) {
            deepTraversal(children[i], isLeave);
          }
        }
      }
    }

    resultTree = resultTree.filter(item => {
      if (item !== undefined) {
        return item;
      }
    })
    if (keyword && keyword.length && keyword.length > 0) {
      return resultTree;
    } else {
      return this.resultTree;
    }
  }

  //过滤树：返回树搜索的节点被标记
  getFilterTree(keyword) {
    this.originList.map((item) => {
      if (keyword && keyword.length && keyword.length > 0) {
        if (item[this.options.filterKey].match(keyword)) {
          item._filter = true;
        } else {
          item._filter = false;
        }
      } else {
        item._filter = false;
      }
    });
    this.resultTree = this.convertListToTree(this.originList);
    return this.resultTree;
  }

  //过滤列表:返回列表
  getFilterList(keyWord) {
    let originList = this.deepCopy(this.originList);
    let fList = [];
    originList.map((item) => {
      if (item[this.options.filterKey].match(keyWord)) {
        fList.push(item);
      }
    });
    return fList;
  }

  getResult() {
    return this.resultTree;
  }

  getOrigin() {
    return this.originList;
  }

  init() {
    let originList = this.options.originList;
    if (this.options.originType === 'list') {
      originList && originList.length && originList.map(item => {
        item.title = item[this.nodeConfig.title];
        item._originKey = item._originKey || item.key;
        item.key = item[this.nodeConfig.key];
      });
      //如果传入的是数组
      this.originList = originList;
    } else if (this.options.originType === 'tree') {
      //如果传入的是数组，但是每一个元素都是节点
      originList && originList.length && originList.map(item => {
        this.deepTraversal(item);
      });
    }
    this.resultTree = this.convertListToTree(this.originList);
  }

  //获取全部节点的树
  getAllNodeTree() {
    let originList = this.deepCopy(this.originList);
    this.resultTree = this.convertListToTree(originList);
    return this.resultTree;
  }

  //获取启用节点的树
  getOnlyEnabledTree() {
    let originList = this.deepCopy(this.originList);
    originList.map((item, index) => {
      if (!item.enabled) {
        originList.splice(index, 1);
      }
    });
    this.resultTree = this.convertListToTree(originList);
    return this.resultTree;
  }

  //转树
  //把列表转为树形结构
  convertListToTree(olist) {
    let list = this.deepCopy(olist);
    let that = this;

    function getJsonTree(data, parentId) {
      let itemArr = [];
      for (let i = 0; i < data.length; i++) {
        let node = data[i];
        if (node.parentId === parentId) {
          if (node.children) {
            node.children.push(getJsonTree(data, node[that.nodeConfig.key]));
          } else {
            node.children = getJsonTree(data, node[that.nodeConfig.key]);
          }
          if (node.children && node.children.length === 0) {
            delete node.children;
          }
          itemArr.push(node);
        }
      }
      return itemArr;
    }

    return getJsonTree(list, '0');
  }

  //深度遍历tree,把树形节点转为list
  deepTraversal(node) {
    if (node !== null) {
      node.title = node[this.nodeConfig.title];
      node._originKey = node._originKey || node.key;
      node.key = node[this.nodeConfig.key];
      this.originList.push(node);
      let children = node.children;
      delete node.children;
      if (children) {
        for (let i = 0; i < children.length; i++) {
          this.deepTraversal(children[i]);
        }
      }
    }
    return node;
  }

  //深度拷贝
  deepCopy(obj) {
    return JSON.parse(JSON.stringify(obj));
  }
}

export default ListTranformTree;

//使用方式
// 参数
let optionsDefault = {
  originType: 'list',//tree
  originList: [],
  topNodeId: '0',//默认顶级节点没有parentId
  limitKeys: [],//只要某些节点,
  filterKey: 'resourceName',//过滤的时候，匹配的字段
};
// 节点配置
let nodeConfigDefault = {
  key: "resourceId",
  title: "resourceName",
};
//let listTranformTree = new ListTranformTree(optionsDefault, nodeConfigDefault);
//方法
//获取源列表
//console.log(listTranformTree.getOrigin());
//获取转换后的树
//console.log(listTranformTree.getResult());
//获取通过关键字过滤后的树
//console.log(listTranformTree.getFilterList());
//获取仅仅启用的节点
//console.log(listTranformTree.getOnlyEnabledTree());
//获取指定节点
//console.log(listTranformTree.getTargetNodeByKey(list,123));

